package com.hex.es.component;

import com.google.common.collect.Lists;
import com.hex.es.annotation.EsBuildParamTypeInfo;
import com.hex.es.service.ReturnSearchInterface;
import com.hex.es.service.impl.ReturnDefaultImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 查询执行器路由类
 * @author: Hex
 * @date: 2019/11/13 16:29
 */
@Component
@Slf4j
public class ReturnSearchRouter implements ApplicationContextAware {

    @Resource
    private ReturnDefaultImpl returnDefault;

    private static List<ReturnSearchInterface> ROUTE_LIST = Lists.newArrayList();

    /**
     * 路由
     * 未匹配到路由，则执行默认执行器
     * @param method
     * @param esBuildParamTypeInfo
     * @param searchQuery
     * @return
     * @throws Exception
     */
    public Object route(Method method, EsBuildParamTypeInfo esBuildParamTypeInfo, SearchQuery searchQuery) throws Exception {
        for (ReturnSearchInterface searchInterface : ROUTE_LIST) {
            if (searchInterface.check(method,esBuildParamTypeInfo)) {
                return searchInterface.search(method,esBuildParamTypeInfo,searchQuery);
            }
        }
        return returnDefault.search(method,esBuildParamTypeInfo,searchQuery);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String,ReturnSearchInterface> serviceMap = applicationContext.getBeansOfType(ReturnSearchInterface.class);
        serviceMap.forEach((key,value) -> ROUTE_LIST.add(value));
        ROUTE_LIST=ROUTE_LIST.stream().sorted(Comparator.comparing(ReturnSearchInterface::getOrder).reversed()).collect(Collectors.toList());
    }
}
